/*
Papildināt:
- read benefit
- write benefit
- ?
*/


$(document).ready(function(){
	$('#raids > li').each(function(k, el){
		$(el).bind({
			'click' : function(){
				switchRaid($(this));
			}
		});
	});
	
	$('#currentdiscs').bind({
		'change' : function(){
			checkAllowedCount($(this));
			switchRaid($('#raids > .active'));
		}
	});
	
	$('#r').bind({
		'change' : function(){
			switchRaid($('#raids > .active'));
		}
	});
	
	$('#ecc_disc').bind({
		'change' : function(){
			switchRaid($('#raids > .active'));
		}
	});
	
	switchRaid($('#raid0'));
});

function switchRaid(caller){
	var disc_failure_rate = $('#failure > #r').val() / 100;
	
	switch($(caller).attr('id')){
		
		case 'raid0'://1-(1-r)^n
			$('#mindiscs > #count').html('2');
			checkAllowedCount($('#currentdiscs'));
			var disc_count = $('#currentdiscs').val();
			
			showRaidData(disc_count, 1, 'Nav', 1 - Math.pow((1 - disc_failure_rate), disc_count),null,null,disc_count*4);
				
			moveDoc(disc_count, caller.attr('id'));
			break;
			
		case 'raid1':
			$('#mindiscs > #count').html('2');
			checkAllowedCount($('#currentdiscs'));
			var disc_count = $('#currentdiscs').val();
			
			showRaidData(disc_count, 1 / disc_count, 'Ja nobrūk ' + (disc_count - 1 ) + (disc_count - 1  == 1 ? ' disks' : ' diski'), Math.pow(disc_failure_rate, disc_count),null,null,/*disc_count*/4);
		
			moveDoc(disc_count, caller.attr('id'));
			break;
			
			
			
		case 'raid2':
			$('#mindiscs > #count').html('3');
			checkAllowedCount($('#currentdiscs'));
			
			var disc_count = $('#currentdiscs').val();
			
			var power = Math.log(disc_count - 1) / Math.log(2);
			var space_eff = 1 - 1 / disc_count * power;
			var tolerance = 'Var atjaunoties no 1 diska nobrukšanas vai salabot sabojātus datus vai paritāti, kad bojātā bita atbilstošie dati / paritāte ir nebojāti';
							
			var ecc_disc_count = Math.ceil(Math.log(disc_count-1)/(Math.log(2)));
			
			showRaidData(disc_count - ecc_disc_count, space_eff, tolerance, 'mainīgs', null, null, (disc_count - ecc_disc_count) * 4, caller.attr('id'));
			
			moveDoc(disc_count, caller.attr('id'),'Heminga kļūdu korekcijas kods', ecc_disc_count);
			createParityDisc(ecc_disc_count, 'Heminga kļūdu korekcijas kods: ');
			break;
		case 'raid3':
			$('#mindiscs > #count').html('3');
			checkAllowedCount($('#currentdiscs'));
			var disc_count = $('#currentdiscs').val();
			
			var failure_rate = disc_count * (disc_count - 1) * Math.pow(disc_failure_rate, 2);
			showRaidData(disc_count, 1 - 1 / disc_count, 'Ja nobrūk 1 disks', failure_rate, null, null, disc_count * 4, caller.attr('id'));
			
			moveDoc(disc_count, caller.attr('id'), 'Paritāte', 1);
			createParityDisc(1, 'Paritāte');
			break;
		case 'raid4':
			$('#mindiscs > #count').html('3');
			checkAllowedCount($('#currentdiscs'));
			var disc_count = $('#currentdiscs').val();
			
			var failure_rate = disc_count * (disc_count - 1) * Math.pow(disc_failure_rate, 2);
			showRaidData(disc_count, 1 - 1 / disc_count, 'Ja nobrūk 1 disks', failure_rate, null, null, disc_count * 4);
			
			moveDoc(disc_count, caller.attr('id'),'Paritāte', 1);
			createParityDisc(1, 'Paritāte');
			break;
		case 'raid5':
			$('#mindiscs > #count').html('3');
			checkAllowedCount($('#currentdiscs'));
			var disc_count = $('#currentdiscs').val();
			
			var failure_rate = disc_count * (disc_count - 1) * Math.pow(disc_failure_rate, 2);
			showRaidData(disc_count, 1 - 1 / disc_count, 'Ja nobrūk 1 disks', failure_rate,null,null,disc_count*(disc_count-1));
			moveDoc(disc_count, caller.attr('id'), 'Paritāte', 1);
			
			break;
		case 'raid6':
			$('#mindiscs > #count').html('4');
			checkAllowedCount($('#currentdiscs'));
			var disc_count = $('#currentdiscs').val();
			
			var failure_rate = disc_count * (disc_count - 1) * (disc_count - 2) * Math.pow(disc_failure_rate, 3);
			showRaidData(disc_count, 1 - 2 / disc_count, 'Ja nobrūk 2 diski', failure_rate,null,null,disc_count*(disc_count-2));
			moveDoc(disc_count, caller.attr('id'), 'Paritāte', 1);
			break;
		default:
			break;
	}
	
	$('#raids > li').removeClass('active');
	$(caller).addClass('active');
}

function checkAllowedCount(caller){
	var allowedCount = $('#mindiscs > #count').html();
	
	if (parseInt($(caller).val(),10) < parseInt(allowedCount,10)){
		$(caller).val(allowedCount);
	}
}

function showRaidData(disc_count, space_eff, fault_tolerance, failure_rate, rbenefit, wbenefit, part_count,raid_type){
	disc_count = typeof(disc_count) != 'undefined' ? disc_count : 'ERROR';
	space_eff = typeof(space_eff) != 'undefined' ? space_eff : 'ERROR';
	fault_tolerance = typeof(fault_tolerance) != 'undefined' ? fault_tolerance : 'ERROR';
	failure_rate = typeof(failure_rate) != 'undefined' ? failure_rate : 'ERROR';
	
	$('#animation').empty();
	$('#space_eff > #eff_points').html(roundNumber(space_eff * 100, 3) + '%');
	$('#faults > #tolerance').html(fault_tolerance);
	
	$('#failure > #rate').html(failure_rate == 'mainīgs' ? 'mainīgs' : roundNumber(failure_rate * 100, 3) + '%');
	//$('#rbenefit').html(rbenefit);
	//$('#wbenefit').html(wbenefit);

	var doc = $(document.createElement('div')).addClass('doc').attr('id', 'source').html('Datu bloks');
	if(raid_type == 'raid5'){
	} else {
		for (var ii = 0; ii < part_count; ii++){
			var block = $(document.createElement('div')).addClass('fragment_file').html((raid_type == 'raid3' ? 'Baitu fragments: ' : (raid_type == 'raid2' ? 'Bitu fragments: ' : 'Fragments: ')) + (ii + 1));
			doc.append(block);
		}
	}
	$('#animation').append(doc);
	
	for (i = 0; i < disc_count; i++){
		var disc = $(document.createElement('div')).addClass('disc').html('Disks ' + (i + 1)).attr('id', 'disc' + i);
		$('#animation').append(disc);
	}
}

function moveDoc(disc_count, part_type, parity_type, parity_disc_count){

    var disc0s = 0;

    if ($('#disc0').length){
        disc0s = $('#disc0').position().top;
    }

    if ($('#source').position().top + $('#source').height() < disc0s) {
    	$('#source').css('top', $('#source').position().top + 1);
    	setTimeout(function(){ moveDoc (disc_count, part_type, parity_type, parity_disc_count); }, 20);
    } else {
		setTimeout(function(){ moveDocsParts(disc_count, part_type, parity_type, parity_disc_count); }, 500);
    }
}

function createParityDisc(disc_count, parity_type){
	for (i = 0; i < disc_count; i++){
		var disc = $(document.createElement('div')).addClass('disc').html('Disks ' + (i + 1) + ' - ' + parity_type).attr('id', 'disc_parity_' + i);
		$('#animation').append(disc);
	}
}
function appendToDisk(id, value){
	$('#disc' + id).append(value);
}
function showBlock(block){
	$(block).show();
}

function moveDocsParts(count, part_type, parity_type, parity_disc_count){

	switch(part_type){
		case 'raid0':
			var ii = 0;
			$.each($('#source').children('.fragment_file'), function(index, value) { 
				//alert(index + ': ' + value);
				appendToDisk(ii++%count,value);	 
			});
			break;
		case 'raid1':
			for (i = 0; i < count; i++){
				var nd = $('#source').clone();
				$.each(nd.children('.fragment_file'), function(index, value) { 
				$('#disc' + i).append(value);
				});
			}
			break
		case 'raid2':
			var ii = 0;
			var cc = 0;
			$.each($('#source').children('.fragment_file'), function(index, value) { 
				appendToDisk(ii++%count,value);
				cc++
			});
			
			
			var jp = 0;
			var i = 0;
			for(i = 0; i <= cc; i++){				
				if(i % count == 0 && i != 0){					
					for(var j = 0; j < parity_disc_count; j++){
						var ecc = $(document.createElement('div')).addClass('fragment_file').addClass('ecc').html(parity_type);
						appendToDisk('_parity_' + j, ecc);
					}
				}
			}
			if(i > cc && ((i - 1) % count) != 0){
				for(var j = 0; j < parity_disc_count; j++){
					var ecc = $(document.createElement('div')).addClass('fragment_file').addClass('ecc').html(parity_type);
					appendToDisk('_parity_' + j, ecc);
				}
			}
			break;
		case 'raid3':
			var ii = 0;
			var cc = 0;
			$.each($('#source').children('.fragment_file'), function(index, value) { 
				appendToDisk(ii++%count,value);
				cc++
			});
			
			var jp = 0;
			for(var i = 0; i <= cc; i++){				
				if(i % count == 0 && i != 0){
					var ecc = $(document.createElement('div')).addClass('fragment_file').addClass('ecc').html(parity_type);
					appendToDisk('_parity_' + jp++%parity_disc_count, ecc);
				}
			}
			break;
		case 'raid4':
			var ii = 0;
			var cc = 0;
			$.each($('#source').children('.fragment_file'), function(index, value) { 
				appendToDisk(ii++%count,value);
				cc++
			});
			
			var jp = 0;
			for(var i = 0; i <= cc; i++){				
				if(i % count == 0 && i != 0){
					var ecc = $(document.createElement('div')).addClass('fragment_file').addClass('ecc').html(parity_type);
					appendToDisk('_parity_' + jp++%parity_disc_count, ecc);
				}
			}
			break;
		case 'raid5':
			var ii = 0;
			var cc = 0;
			$.each($('#source').children('.fragment_file'), function(index, value) { 
				//alert(index + ': ' + value);
				cc = Math.floor(ii / count);
				
				//alert (cc + " " + ii%count);
				if((count - cc - 1 ) == (ii%count))/*((ii%(count-1))==0 && ii != 0 && ii != )*/{
					cc2 = Math.floor(ii / (count));
					var tmpId = ii++%count;
					var block = $(document.createElement('div')).addClass('fragment_file').addClass('test_'+cc2+'__ii_'+ii +'___' + tmpId).addClass('ecc').html('Paritāte');
					$(block).hide();
					
					appendToDisk(tmpId,block);
					setTimeout(function() {showBlock(block);},1000*(cc2));
				}
				 cc2 = Math.floor(ii / (count));
					var tmpId = ii++%count;
					
					$(value).addClass('test_'+cc2+'__ii_'+ii +'___' + tmpId);
					$(value).hide();
					appendToDisk(tmpId,value);	
					setTimeout(function() {showBlock(value);},1000*(cc2));
			});
			break;
		case 'raid6':
			var ii = 0;
			var cc = 0;
			$.each($('#source').children('.fragment_file'), function(index, value) { 
				//alert(index + ': ' + value);
				cc = Math.floor(ii / count);
				if((count - cc  -2) == (ii%count))/*((ii%(count-1))==0 && ii != 0 && ii != )*/{
					cc2 = Math.floor(ii / (count));
					var tmpId = ii++%count;
					var block = $(document.createElement('div')).addClass('fragment_file').addClass('test_'+cc2+'__ii_'+ii +'___' + tmpId).addClass('ecc22').html('Paritāte');
					$(block).hide();
					
					appendToDisk(tmpId,block);
					//setTimeout(function() {showBlock(block);},1000*(cc2));
					showBlock(block);
				}
				//alert (cc + " " + ii%count);
				if((count - cc - 1 ) == (ii%count))/*((ii%(count-1))==0 && ii != 0 && ii != )*/{
					cc2 = Math.floor(ii / (count));
					var tmpId = ii++%count;
					var block = $(document.createElement('div')).addClass('fragment_file').addClass('test_'+cc2+'__ii_'+ii +'___' + tmpId).addClass('ecc').html('Paritāte');
					$(block).hide();
					
					appendToDisk(tmpId,block);
					//setTimeout(function() {showBlock(block);},1000*(cc2));
					showBlock(block);
				} 
				
				 cc2 = Math.floor(ii / (count));
					var tmpId = ii++%count;
					
					$(value).addClass('test_'+cc2+'__ii_'+ii +'___' + tmpId);
					$(value).hide();
					appendToDisk(tmpId,value);	
					showBlock(value);
					//setTimeout(function() {showBlock(value);},1000*(cc2));
			});
			cc2 = Math.floor(ii / (count));
			var tmpId = ii++%count;
			var block = $(document.createElement('div')).addClass('fragment_file').addClass('test_'+cc2+'__ii_'+ii +'___' + tmpId).addClass('ecc22').html('Paritāte');
			$(block).hide();
			
			appendToDisk(tmpId,block);
			showBlock(block);

			break;
		default:
			break;
		}


	$('#source').css('top', '0').css('display', 'none');
}

function roundNumber(num, dec) {
	var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
	return result;
}
